#ifndef _QUEUENETWORKMODEL_H
#define	_QUEUENETWORKMODEL_H

#ifdef	__cplusplus
extern "C" {
#endif

    #include "csim.h"
    #include "request.h"
    #include "Config.h"



    //Queue Network Building Block

    typedef struct {
        double queue_len;
        double utilization;
        double response_time;
        double service_time;
        double throughput;

        double completion;

    } FacilityPerformanceIndex;

    typedef struct {
        FACILITY cpu;
        FACILITY disk;
        char * name;

        FacilityPerformanceIndex * cpu_server_index;
        FacilityPerformanceIndex * disk_server_index;
    } ServerFacility;

    typedef struct {
        ServerFacility** servers;
        FACILITY lan;
        FACILITY web_switch;
        int n_servers;
        char* name;

        FacilityPerformanceIndex * lan_index;
        FacilityPerformanceIndex * web_switch_index;
        FacilityPerformanceIndex * cpu_local_area_avg_index;
        FacilityPerformanceIndex * disk_local_area_avg_index;

        TABLE local_area_response_time;
        TABLE *local_area_class_response_time;
        int n_class;
    } LocalAreaFacility;

    typedef struct {
        LocalAreaFacility **local_areas;
        int n_loc_areas;
        char *name;
        TABLE network_response_time;
        TABLE *network_class_response_time;
        int n_class;
        FACILITY link_cdd;
        FACILITY link_in;
        FACILITY link_out;

        FacilityPerformanceIndex * link_cdd_index;
        FacilityPerformanceIndex * link_in_index;
        FacilityPerformanceIndex * link_out_index;
        FacilityPerformanceIndex * lan_network_avg_index;
        FacilityPerformanceIndex * web_switch_network_avg_index;
        FacilityPerformanceIndex * cpu_network_avg_index;
        FacilityPerformanceIndex * disk_network_avg_index;
    } NetworkFacility;

    NetworkFacility * network_facility;

    //CiscoDistributedDirector serviceTime
    #define CDD_SERVICE_TIME 0.05

    //specifiche del disco
    #define DISK_CONTROLLER_TIME 0.0002
    #define DISK_SEEK_TIME 0.0074
    #define DISK_SPEED 7200
    #define DISK_TRANSFER_RATE 50.0
    #define DISK_BLOCK_SIZE 2048

    //specifiche delle reti
    #define LAN_BANDWIDTH 100.0

    #define GENERIC_BANDWIDTH 100.0

    //specifiche delle cpu
    #define CPU_SERVICE_RATE 150.0

    //specifiche del webSwitch
    #define WEBSWITCH_SERVICE_RATE 10000.0

    #define N_TOTAL_SERVER  30
    #define N_LOCAL_AREA       4
    
    enum{
        TEXAS  = 0x00,
        VIRGINIA,
        CALIFORNIA,
        FRANCIA
    };
    
    static int server_per_cluster[]={
        6,
        10,
        10,
        4};
    
    static char * cluster_name[]={
        "texas",
        "virginia",
        "california",
        "francia"
    };

    typedef struct{
        int cluster;
        int server;
    } ServerLocation;

    
    ServerLocation getServerLocation(int index);
    void useNetworkFacility(PartitionedRequest *pr);
    void computeNetworkStatistics();
    void printNetworkFacilityPerformanceIndex();
    void printLocalAreaFacilityPerformanceIndex();


    #define MSS 1460.0
    #define TCP_OVERHEAD 20
    #define IP_OVERHEAD	20
    #define DLL_OVERHEAD 18
    #define FRAME_OVERHEAD 18

    #define AVG_SIZE_HTTP_REQUEST 290
    #define AVG_SIZE_HTTP_RESPONSE 290
 
#ifdef	__cplusplus
}
#endif
#endif	/* _QUEUENETWORKMODEL_H */

